package br.unifor.cct.mia.evaluate.pso;

import java.io.File;
import java.io.IOException;
import java.util.List;

import br.unifor.cct.mia.coevolution.InvalidTypeException;
import br.unifor.cct.mia.dataenhancement.Database;
import br.unifor.cct.mia.dataenhancement.GenotypeConverter;
import br.unifor.cct.mia.dataenhancement.Structure;
import br.unifor.cct.mia.dataenhancement.Tuple;
import br.unifor.cct.mia.evaluate.Evaluate;
import br.unifor.cct.mia.evaluate.InvalidLearnerTypeException;
import br.unifor.cct.mia.evaluate.classification.WekaClassification;
import br.unifor.cct.mia.evolutionary.Individual;
import br.unifor.cct.mia.evolutionary.Particula;
import br.unifor.cct.mia.evolutionary.SpeciesConstants;
import br.unifor.cct.mia.pso.PSO;

public class PSOWekaMVEvaluate implements Evaluate {

	private Structure structure;
	private Database database;
	private PSO pso;
	private String[] options;	
	private Tuple tuples;
	private List positions;
	
	public double cost(Individual gen) {		
		double sum = 0;

		try {
			GenotypeConverter converter = new GenotypeConverter();
			File f = converter.convert(gen,SpeciesConstants.MISSING_VALUE,
					"temp/resultPSOMV.txt",structure,database,tuples,positions);

			WekaClassification classificator = new WekaClassification(pso.getLearnerType(),options);
			sum = classificator.evaluate(f);									
		} catch (IOException e1) {
			e1.printStackTrace();
		} catch (InterruptedException e) {
			e.printStackTrace();
		} catch (InvalidTypeException e) {
			e.printStackTrace();
		}			

		return sum;
	}	

	public Object evaluate(Object o, String[] options)
							throws InvalidLearnerTypeException {
		Object[] value = (Object[])o;
		pso = (PSO)value[0];
		structure = (Structure) value[1];
		database = (Database) value[2];
		tuples = (Tuple) value[3];
		positions = (List) value[4];
		this.options = options;  
		
		for (Particula p:pso.getPopulacao()) {
			double fitness = cost(p);
			
			p.setFitness(fitness);
			if ( fitness>p.getPBest().getFitness() ) {
				p.setPBest((Particula)p.clone());
			}
			
			if ( fitness>pso.getBestIndividual().getFitness() ) {
				pso.setBestIndividual((Particula)p.clone());
			}
		}
		return pso.getPopulacao();
	}

}
